home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-12-08 | 9.3 KB | 349 lines | [TEXT/MPS ] |
- /*
- File: Scrollbar.cpp
-
- Contains: Scrollbar class implementation
-
- Written by: Steve Smith
-
- Copyright: © 1995 by Apple Computer, Inc., all rights reserved.
- */
-
- // -- Compiler/Preprocessor Switches --
-
- #ifndef _COMPILERDEFS_
- #include "CompDefs.h"
- #endif
-
- // -- OpenDoc Utilities --
-
- #ifndef _EXCEPT_
- // Exceptions define several important macros (ie. CHECKENV)
- // which are used in the SOM method dispatch glue. If Except.h
- // is not included early enough, exceptions may not be thrown
- // correctly when returning from a SOM method with the "ev" parameter set.
- #include <Except.h>
- #endif
-
- // -- PanelEditor Includes --
-
- #ifndef _SCROLLBAR_
- #include "Scrollbar.h"
- #endif
-
- #ifndef _PANELEDITOR_
- #include "PanelEditor.h"
- #endif
-
- #ifndef _PANELEDITORUTILS_
- #include "PanelEditorUtils.h"
- #endif
-
- #ifndef _PANELEDITORDEF_
- #include "PanelEditorDef.h"
- #endif
-
- // -- OpenDoc Includes --
-
- #ifndef _ODTYPES_
- #include <ODTypes.h>
- #endif
-
- #ifndef SOM_ODFacet_xh
- #include <Facet.xh>
- #endif
-
- #ifndef SOM_ODFrame_xh
- #include <Frame.xh>
- #endif
-
- #ifndef SOM_ODShape_xh
- #include <Shape.xh>
- #endif
-
- #ifndef SOM_ODTransform_xh
- #include <Trnsform.xh>
- #endif
-
- // -- OpenDoc Utilities --
-
- #ifndef _FOCUSLIB_
- #include <FocusLib.h>
- #endif
-
- #ifndef _ODUTILS_
- #include <ODUtils.h>
- #endif
-
- #ifndef _TEMPOBJ_
- #include <TempObj.h>
- #endif
-
- #ifndef _ODDEBUG_
- #include <ODDebug.h>
- #endif
-
- #pragma segment PanelEditorScrollbar
-
-
- //------------------------------------------------------------------------------
- // Method: Constructor
- //------------------------------------------------------------------------------
-
- CScrollbar::CScrollbar()
- {
- fFacet = kODNULL;
- fWindow = kODNULL;
- fControl = kODNULL;
- fInited = kODFalse;
- }
-
- //------------------------------------------------------------------------------
- // Method: Destructor
- //------------------------------------------------------------------------------
-
- CScrollbar::~CScrollbar()
- {
- ASSERT(fInited != kODFalse, kAssertionFailed);
- ASSERT(fFacet != kODNULL, kAssertionFailed);
-
- Environment* ev = somGetGlobalEnvironment();
- CFocusFrame initiateDrawing(ev, fFacet);
-
- // Possibly dangerous, if GrafPort is destroyed before frame is cleaned up, the
- // control will no longer exist... any way to check for dead control?
- // DisposeControl(fControl);
- }
-
- //------------------------------------------------------------------------------
- // Method: InitScrollbar
- //------------------------------------------------------------------------------
-
- void CScrollbar::InitScrollbar(Environment* ev, ODFacet* facet, Rect ctrlRect)
- {
- ASSERT(facet != kODNULL, kAssertionFailed);
-
- ODWindow* odWindow = facet->GetWindow(ev);
-
- fFacet = facet;
- fWindow = (WindowPtr) odWindow->GetPlatformWindow(ev);
-
- CFocusFrame initiateDrawing(ev, fFacet);
- fControl = NewControl(fWindow,&ctrlRect,"\p",false,0,0,0,scrollBarProc,0x0L);
-
- fInited = kODTrue;
- }
-
- //------------------------------------------------------------------------------
- // Method: Size
- // Description: Resize the control using the parameters passed in.
- //------------------------------------------------------------------------------
-
- void CScrollbar::Size(ODUShort width, ODUShort height)
- {
- ASSERT(fInited != kODFalse, kAssertionFailed);
- ASSERT(fControl != kODNULL, kAssertionFailed);
-
- Environment* ev = somGetGlobalEnvironment();
- CFocusFrame initiateDrawing(ev, fFacet);
-
- SizeControl(fControl,width,height);
- }
-
- //------------------------------------------------------------------------------
- // Method: Size
- // Description: Size the control based on the bounding box of the list frame.
- //------------------------------------------------------------------------------
-
- void CScrollbar::Size()
- {
- ASSERT(fInited != kODFalse, kAssertionFailed);
- ASSERT(fFacet != kODNULL, kAssertionFailed);
-
- Environment* ev = somGetGlobalEnvironment();
-
- Rect bounds;
- GetQDFrameBounds(ev, fFacet->GetFrame(ev), &bounds);
-
- this->Size(16,(bounds.bottom-bounds.top));
- }
-
- //------------------------------------------------------------------------------
- // Method: Dirty
- // Description: Mark the scroll bar size as "dirty". Next time we draw it should
- // be updated.
- //------------------------------------------------------------------------------
-
- void CScrollbar::Dirty(ODUShort numItems)
- {
- ASSERT(fInited != kODFalse, kAssertionFailed);
-
- fDirty = kODTrue;
- fNumItems = numItems;
- }
-
- //------------------------------------------------------------------------------
- // Method: Draw
- // Description: Resize the control if it's dirty (which causes drawing as a side
- // effect) or draw the control if it's not.
- //------------------------------------------------------------------------------
-
- void CScrollbar::Draw()
- {
- ASSERT(fInited != kODFalse, kAssertionFailed);
- ASSERT(fControl != kODNULL, kAssertionFailed);
-
- // We always create the control invisible.
- // Make it visible when we draw.
- if ( (**fControl).contrlVis != 0xFF )
- ShowControl(fControl);
-
- // The scroll bar will be "dirty" if it needs to be resized or
- // have its limits adjusted. We use the dirty mechanism to delay
- // the immediate drawing of the control when such calls are made.
- if ( fDirty )
- {
- this->Size();
- this->Adjust(fNumItems);
- fDirty = kODFalse;
- }
- else Draw1Control(fControl);
- }
-
- //------------------------------------------------------------------------------
- // Method: Adjust
- // Description: Calculate the limits for the scrollbar based on the number of
- // items passed in.
- //------------------------------------------------------------------------------
-
- void CScrollbar::Adjust(ODUShort numItems)
- {
- ASSERT(fInited != kODFalse, kAssertionFailed);
- ASSERT(fControl != kODNULL, kAssertionFailed);
-
- Rect ctrlRect = (**fControl).contrlRect;
-
- ODSShort space = (ctrlRect.bottom-ctrlRect.top+1)/kListItemHeight;
-
- ODUShort value;
- if ( numItems-space > 0) value = (numItems - space);
- else value = 0;
-
- this->SetLimits(value);
- }
-
- //------------------------------------------------------------------------------
- // Method: SetLimits
- // Description: Set the control min/max limits. This causes drawing to occur.
- //------------------------------------------------------------------------------
-
- void CScrollbar::SetLimits(ODUShort max, ODUShort min)
- {
- ASSERT(fInited != kODFalse, kAssertionFailed);
- ASSERT(fControl != kODNULL, kAssertionFailed);
- ASSERT(fFacet != kODNULL, kAssertionFailed);
-
- Environment* ev = somGetGlobalEnvironment();
- CFocusFrame initiateDrawing(ev, fFacet);
-
- SetControlMinimum(fControl, min);
- SetControlMaximum(fControl, max);
- }
-
- //------------------------------------------------------------------------------
- // Method: HitTest
- // Description: Determine whether the control was clicked on, and if so where.
- // Store the last valid contact point (partcode) for later use.
- //------------------------------------------------------------------------------
-
- ODBoolean CScrollbar::HitTest(Point where)
- {
- ASSERT(fInited != kODFalse, kAssertionFailed);
- ASSERT(fControl != kODNULL, kAssertionFailed);
- ASSERT(fFacet != kODNULL, kAssertionFailed);
- ASSERT(fWindow != kODNULL, kAssertionFailed);
-
- Environment* ev = somGetGlobalEnvironment();
- CFocusFrame initiateDrawing(ev, fFacet);
-
- ControlHandle control = kODNULL;
- fPartCode = FindControl(where, fWindow, &control);
-
- if ( control != fControl )
- fPartCode = 0;
-
- return fPartCode;
- }
-
- //------------------------------------------------------------------------------
- // Method: Scroll
- // Description: Handle scrolling. Install a scroll tracking proc if the user is
- // not clicking on the "thumb". Scrolling of the content is
- // achieved by translating the internal transform of the list
- // frame.
- //------------------------------------------------------------------------------
-
- void CScrollbar::Scroll(Environment* ev, ODFrame* frame, Point where)
- {
- ASSERT(fInited != kODFalse, kAssertionFailed);
- ASSERT(fFacet != kODNULL, kAssertionFailed);
- ASSERT(fControl != kODNULL, kAssertionFailed);
-
- if ( fPartCode != 0 )
- {
- CFocusFrame initiateDrawing(ev, fFacet);
-
- ScrollDataRec* scrollData = (ScrollDataRec*) ODNewPtr(sizeof(ScrollDataRec));
-
- scrollData->frame = frame;
- scrollData->ev = ev;
-
- if ( fPartCode == kControlIndicatorPart )
- {
- // Determine which direction the user scrolled (up/down)
-
- short vScroll = GetControlValue(fControl);
-
- TrackControl(fControl, where, kODNULL);
-
- vScroll = GetControlValue(fControl) - vScroll;
-
- if ( vScroll != 0 )
- {
- // Adjust the internal transform of the list frame to affect
- // scrolling of the list.
-
- TempODTransform intTransform =
- scrollData->frame->AcquireInternalTransform(ev, kODNULL);
-
- Point offset = intTransform->GetQDOffset(ev);
- offset.v += (-vScroll*kListItemHeight);
- intTransform->SetQDOffset(ev, &offset);
-
- scrollData->frame->ChangeInternalTransform(ev, intTransform, kODNULL);
- scrollData->frame->Invalidate(ev, kODNULL, kODNULL);
- }
- }
- else
- {
- ControlActionUPP scrollProcUPP = NewControlActionProc(ScrollProc);
-
- // Stuff the scroll data structure into the scroll bar we are
- // working with.
- SetControlReference(fControl, (long)scrollData);
-
- // Using the scrollProc, track the users actions.
- TrackControl(fControl, where, scrollProcUPP);
-
- // Clear the refcon to avoid confusion.
- SetControlReference(fControl, 0x0L);
-
- // Delete the routine descriptor.
- DisposeRoutineDescriptor(scrollProcUPP);
- }
-
- ODDisposePtr((ODPtr)scrollData);
- }
- }
-
-
-